#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<stack>
#include<algorithm>
#include<set>
using namespace std;

class Node{
public:
    Node(int row,int column){
        this->row = row;
        this->column = column;
    }
public:
    int row;
    int column;
};

class Solution {
public:
    int removeStones(vector<vector<int>>& stones) {
        //先把节点全部创立
        for(int i = 0;i<stones.size();++i){
            pair<int,int> tempValue = make_pair(stones[i][0],stones[i][1]);
            Node* tempNode = new Node(stones[i][0],stones[i][1]);
            node.insert(make_pair(tempValue,tempNode));
            parents[tempNode] = tempNode;
        }

        //同一行，同一列的合并到同一个集合中；
        for(int i = 0;i<node.size()-1;++i){
            for(int j = i+1;j<node.size();++j){
                if(stones[i][0]==stones[j][0]||stones[i][1] == stones[j][1]){
                    unionSet(node[make_pair(stones[i][0],stones[i][1])],node[make_pair(stones[j][0],stones[j][1])]);     
                }
            }
        }

        //计算集合数
        set<Node*> S;
        for(map<pair<int,int>, Node*>::iterator i = node.begin();i!=node.end();++i){
            Node* father = findFather(i->second);
            S.insert(father);
        }
        return stones.size()-S.size();
    }

    Node* findFather(Node* a){
        stack<Node*> path;
        while (parents[a]!=a)
        {
            path.push(a);
            a = parents[a];
        }
        while(!path.empty()){
            parents[path.top()] = a;
            path.pop();
        }
        return a;
    }

    bool isSameSet(Node* a,Node* b){
        return findFather(a)==findFather(b);
    }

    void unionSet(Node* a,Node* b){
        if(!isSameSet(a,b)){
            Node* afather = findFather(a);
            Node* bfather = findFather(b);
            parents[afather] = bfather;          
        }
    }

public:
    map<pair<int,int>, Node*> node;
    map<Node*,Node*> parents;
};


int main(){
    Solution S;
    vector<vector<int>> stones = {{0,0}};
    cout<<S.removeStones(stones)<<endl;
}